import { Injectable, ConflictException, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, SelectQueryBuilder } from 'typeorm';
import * as bcrypt from 'bcryptjs';
import { User, Role } from '@app/entities';
import { 
  CreateUserDto, 
  UpdateUserDto, 
  QueryUsersDto, 
  BatchUserActionDto,
  ResetPasswordDto 
} from '../dto';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Role)
    private readonly roleRepository: Repository<Role>,
  ) {}

  async findAll(query: QueryUsersDto) {
    const queryBuilder = this.createBaseQuery();
    
    // 搜索条件
    if (query.search) {
      queryBuilder.andWhere(
        '(user.username LIKE :search OR user.nickName LIKE :search OR user.email LIKE :search)',
        { search: `%${query.search}%` }
      );
    }

    // 状态筛选
    if (query.status !== undefined) {
      queryBuilder.andWhere('user.status = :status', { status: query.status });
    }

    // 性别筛选
    if (query.gender !== undefined) {
      queryBuilder.andWhere('user.gender = :gender', { gender: query.gender });
    }

    // 来源筛选
    if (query.from) {
      queryBuilder.andWhere('user.from = :from', { from: query.from });
    }

    // 角色筛选
    if (query.role) {
      queryBuilder.andWhere('roles.name = :role', { role: query.role });
    }

    // 排序
    const sortBy = query.sortBy || 'createdAt';
    const sortOrder = query.sortOrder || 'DESC';
    queryBuilder.orderBy(`user.${sortBy}`, sortOrder);

    // 分页
    const page = query.page || 1;
    const limit = query.limit || 10;
    const skip = (page - 1) * limit;

    queryBuilder.skip(skip).take(limit);

    const [users, total] = await queryBuilder.getManyAndCount();

    return {
      users: users.map(user => this.formatUserResponse(user)),
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit),
      },
    };
  }

  async findOne(id: number): Promise<User> {
    const user = await this.userRepository.findOne({
      where: { id },
      relations: ['roles'],
    });

    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    return user;
  }

  async findByUsernameOrEmail(usernameOrEmail: string): Promise<User | null> {
    const user = await this.userRepository.findOne({
      where: [
        { username: usernameOrEmail },
        { email: usernameOrEmail },
      ],
      relations: ['roles'],
    });
    return user || null;
  }

  async create(createUserDto: CreateUserDto): Promise<User> {
    // 检查用户名是否已存在
    const existingUser = await this.userRepository.findOne({
      where: [
        { username: createUserDto.username },
        { email: createUserDto.email }
      ],
    });

    if (existingUser) {
      throw new ConflictException('用户名或邮箱已存在');
    }

    // 获取角色
    const roles = await this.roleRepository.findByIds(createUserDto.roleIds);
    if (roles.length !== createUserDto.roleIds.length) {
      throw new BadRequestException('部分角色不存在');
    }

    // 创建用户
    const user = this.userRepository.create({
      ...createUserDto,
      password: await this.hashPassword(createUserDto.password),
      roles,
    });

    return await this.userRepository.save(user);
  }

  async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {
    const user = await this.findOne(id);

    // 如果更新用户名或邮箱，检查是否冲突
    if (updateUserDto.username || updateUserDto.email) {
      const conflictConditions = [];
      if (updateUserDto.username) {
        conflictConditions.push({ username: updateUserDto.username });
      }
      if (updateUserDto.email) {
        conflictConditions.push({ email: updateUserDto.email });
      }

      const existingUser = await this.userRepository.findOne({
        where: conflictConditions,
      });

      if (existingUser && existingUser.id !== id) {
        throw new ConflictException('用户名或邮箱已存在');
      }
    }

    // 处理角色更新
    if (updateUserDto.roleIds) {
      const roles = await this.roleRepository.findByIds(updateUserDto.roleIds);
      if (roles.length !== updateUserDto.roleIds.length) {
        throw new BadRequestException('部分角色不存在');
      }
      user.roles = roles;
    }

    // 处理密码更新
    if (updateUserDto.password) {
      updateUserDto.password = await this.hashPassword(updateUserDto.password);
    }

    Object.assign(user, updateUserDto);
    return await this.userRepository.save(user);
  }

  async remove(id: number): Promise<void> {
    const user = await this.findOne(id);
    await this.userRepository.remove(user);
  }

  async resetPassword(id: number, resetPasswordDto: ResetPasswordDto): Promise<void> {
    if (resetPasswordDto.newPassword !== resetPasswordDto.confirmPassword) {
      throw new BadRequestException('两次输入的密码不一致');
    }

    const user = await this.findOne(id);
    user.password = await this.hashPassword(resetPasswordDto.newPassword);
    await this.userRepository.save(user);
  }

  async batchAction(batchActionDto: BatchUserActionDto): Promise<any> {
    const { userIds, action } = batchActionDto;
    
    switch (action) {
      case 'activate':
        await this.userRepository.update(userIds, { status: 1 });
        break;
      case 'deactivate':
        await this.userRepository.update(userIds, { status: 0 });
        break;
      case 'delete':
        await this.userRepository.delete(userIds);
        break;
      case 'assignRole':
        if (batchActionDto.roleIds && batchActionDto.roleIds.length > 0) {
          const roles = await this.roleRepository.findByIds(batchActionDto.roleIds);
          for (const userId of userIds) {
            const user = await this.findOne(userId);
            user.roles = roles;
            await this.userRepository.save(user);
          }
        }
        break;
      default:
        throw new BadRequestException('不支持的操作类型');
    }

    return {
      processed: userIds.length,
      action,
    };
  }

  async banUser(id: number): Promise<void> {
    await this.userRepository.update(id, { status: 0 });
  }

  async unbanUser(id: number): Promise<void> {
    await this.userRepository.update(id, { status: 1 });
  }

  async getUserStats(id: number): Promise<any> {
    const user = await this.findOne(id);
    
    // TODO: 实现用户统计逻辑
    // 这里可以查询用户的文章数、评论数等统计信息
    
    return {
      user: this.formatUserResponse(user),
      stats: {
        postsCount: 0,
        publishedPostsCount: 0,
        draftPostsCount: 0,
        totalViews: 0,
        totalLikes: 0,
        totalComments: 0,
        joinDate: user.createdAt,
        lastLoginAt: user.lastLoginAt,
      },
    };
  }

  private createBaseQuery(): SelectQueryBuilder<User> {
    return this.userRepository
      .createQueryBuilder('user')
      .leftJoinAndSelect('user.roles', 'roles');
  }

  private async hashPassword(password: string): Promise<string> {
    const saltRounds = 10;
    return await bcrypt.hash(password, saltRounds);
  }

  private formatUserResponse(user: User): any {
    const { password, ...userWithoutPassword } = user;
    return {
      ...userWithoutPassword,
      roleNames: user.roleNames,
      primaryRole: user.primaryRole,
      isAdmin: user.isAdmin,
    };
  }
}
